<template>
  <canvas class="canvas" ref="canvas" :id="canvasId" :canvas-id="canvasId" @touchstart="touchstart"
    @touchmove="touchmove" @touchend="touchend" @touchcancel="touchend"></canvas>
</template>

<script setup>
import { getCurrentInstance, ref, watch, onBeforeUnmount } from "vue"
import echarts from "@/components/Echarts/utils/echarts.min.js"

import $u from "@/u"

const _this = getCurrentInstance()
const canvasId = `Echarts_${_this.uid}`

const props = defineProps({
  option: {
    type: Object,
    default: () => ({}),
  },
})

const emit = defineEmits(["eChartClick", "eChartReady"])

const { devicePixelRatio } = $u.getSystemInfoSync()

let timer = null
let chart = null
let canvas = ref(null)

watch(
  props,
  async () => {
    // 防抖
    clearTimeout(timer)
    timer = setTimeout(async () => {

      if (!chart) {

        // #ifdef H5
        canvas = canvas.value.$el
        let { offsetWidth, offsetHeight } = canvas.parentNode
        chart = echarts.init(canvas, null, { renderer: 'canvas', renderOptions: { canvas: { enableCanvasAntialiasing: true } }, width: offsetWidth, height: offsetHeight })
        chart.on('click', (e) => emit('eChartClick', e))
        emit("eChartReady", chart)
        // #endif

        // #ifdef MP
        await new Promise((resolve) => {
          $u.createSelectorQuery()
            .in(_this)
            .select(`#${canvasId}`)
            .fields({ context: true, size: true }, () => { })
            .exec(([{ context: canvas, width, height }]) => {
              canvas.dpr = devicePixelRatio
              canvas.getContext = () => canvas
              canvas.addEventListener = canvas.removeEventListener = () => { }
              canvas.createRadialGradient = () => ({ addColorStop: () => { } })
              chart = echarts.init(canvas, null, { width, height })
              chart.on('click', (e) => emit('eChartClick', e))
              emit("eChartReady", chart)
              resolve(true)
            })
        })
        // #endif
      }
      chart.setOption(props.option, true)

    }, 200)
  },
  {
    immediate: true,
  }
)

const touchstart = (e) => {
  if (!chart || e.touches.length < 1) return false
  let handler = chart.getZr().handler
  let touch = e.touches[0]
  handler.dispatch('mousedown', { zrX: touch.x, zrY: touch.y, preventDefault: () => { }, stopPropagation: () => { }, cancelBubble: false })
  handler.dispatch('mousemove', { zrX: touch.x, zrY: touch.y, preventDefault: () => { }, stopPropagation: () => { }, cancelBubble: false })
  handler.processGesture(wrapTouch(e), 'start')
}

const touchmove = (e) => {
  if (!chart || e.touches.length < 1) return false
  let touch = e.touches[0]
  let handler = chart.getZr().handler
  handler.dispatch('mousemove', { zrX: touch.x, zrY: touch.y, preventDefault: () => { }, stopPropagation: () => { }, cancelBubble: false })
  handler.processGesture(wrapTouch(e), 'change')
}

const touchend = (e) => {
  if (!chart) return false
  let touch = e.changedTouches ? e.changedTouches[0] : {}
  let handler = chart.getZr().handler
  handler.dispatch('mouseup', { zrX: touch.x, zrY: touch.y, preventDefault: () => { }, stopPropagation: () => { }, cancelBubble: false })
  handler.dispatch('globalout', { zrX: touch.x, zrY: touch.y, preventDefault: () => { }, stopPropagation: () => { }, cancelBubble: false })
  handler.processGesture(wrapTouch(e), 'end')
}

const wrapTouch = (event) => {
  for (let i = 0, l = event.touches.length; i < l; ++i) {
    let touch = event.touches[i]
    touch.offsetX = touch.x
    touch.offsetY = touch.y
  }
  return event
}

onBeforeUnmount(() => {
  chart?.dispose()
})
</script>

<style lang="scss" scoped>
.canvas {
  width: 100%;
  height: 100%;
}
</style>
